package com.tangding.hprose.api.server.command.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.google.common.base.Strings;
import com.tangding.cache.GamesConfigCache;
import com.tangding.common.exception.GException;
import com.tangding.common.tools.ErrorConstants;
import com.tangding.common.utils.AES128;
import com.tangding.common.utils.DateUtils;
import com.tangding.common.utils.Utils;
import com.tangding.config.Config;
import com.tangding.hprose.api.server.command.Command;
import com.tangding.hprose.api.server.command.Response;
import com.tangding.net.pool.BaseNettySessionPool;
import com.tangding.service.dao.games.config.GamesConfigRepository;
import com.tangding.service.dao.role.PermissionRepository;
import com.tangding.service.dao.role.RoleRepository;
import com.tangding.service.dao.user.LoginRepository;
import com.tangding.service.dao.user.UserRepository;
import com.tangding.service.entity.role.Permission;
import com.tangding.service.entity.role.Role;
import com.tangding.service.entity.user.User;

/**
 * @description 
 *
 * @author Ranger
 * @version 2017年11月21日_下午2:00:19
 *
 */
@Component("login")
public class Login implements Command {
	
	@Autowired
	UserRepository userRepository;
	
	@Autowired
	RoleRepository roleRepository;
	
	@Autowired
	PermissionRepository permissionRepository;
	
	@Autowired
	GamesConfigRepository configRepository;
	
	@Autowired
	BaseNettySessionPool pool;

	@Autowired
	LoginRepository loginRepository;
	
	@Override
	public Response exe(Object... params) throws GException {
		@SuppressWarnings("unchecked")
		Map<String, Object> map = (Map<String, Object>) params[0];
		String account = (String) map.get("account");
		String pwd = (String) map.get("pwd");
		User user = userRepository.findUsersByUidAndPwd(account, pwd);
		if (user == null) {
			throw new GException(ErrorConstants.ERR_WRONG_PASSWORD);
		}
		
		if (user.isAvailable() != null && !user.isAvailable()) {//已经被删除的账号
			throw new GException(ErrorConstants.ERR_LOCK_ACCOUNT);
		}
		
		if (Strings.isNullOrEmpty(user.getChannelId())) {//补救措施
			user.setChannelId(Utils.uuid());
			userRepository.updateUser(user);
		}
		
		if (user.isAvailable() == null) {//补救措施
			user.setAvailable(true);
			userRepository.updateUser(user);
		}
		
		Map<String, Object> data = new HashMap<>();
		data.put("name", user.getName());
		data.put("uid", user.getUid());
		String puid = Strings.isNullOrEmpty(user.getPuid()) ? "-1" : user.getPuid();
		data.put("puid", puid);
		data.put("pname", Strings.isNullOrEmpty(user.getPname()) ? "系统" : user.getPname());
		
		Set<Integer> roles = user.getRoles();
		Set<Permission> permissions = new HashSet<>();
		if (roles != null) {
			roles.forEach(roleId -> {
				Role role = roleRepository.getRole(roleId);
				List<Integer> permissionIds = role.getPermission();
				if (permissionIds != null) {
					permissionIds.forEach(permissionId -> {
						if (permissionRepository.getPermissions().containsKey(permissionId)) {
							permissions.add(permissionRepository.getPermissions().get(permissionId));
						}
					});
				}
			});
		}
		
		
		String accessToken = Utils.uuid();
		data.put("accessToken", accessToken);
		data.put("seceret", AES128.Encrypt(account + "|" + accessToken + "|" + DateUtils.getNow(), Config.AES128_KEY));
		data.put("channelId", user.getChannelId());
		
		//检查是否要踢出原来的管理端
		String token = loginRepository.get(account);
		if (!Strings.isNullOrEmpty(token)) {//需要踢出原来的登录
			pool.doResponse(account, "RepeatedLogin", null);
			pool.dropSession(account);
		}
		loginRepository.push(account, accessToken);//缓存
		
		data.put("permissions", permissions);
		
		pushGameSettings(data);//添加游戏配置返回
		
		return doResponseSucc(data);
	}
	
	private void pushGameSettings(Map<String, Object> response) {
		Set<String> gamesName = configRepository.getGamesName();
		if (gamesName != null && gamesName.size() > 0) {
			List<Map<String, Object>> list = new ArrayList<>();
			for (String gameName : gamesName) {
				Map<String, Object> map = new HashMap<>();
				/*Map<String, Object> data = new HashMap<>();
				data.put("head", configRepository.getNormalDataConfigs(gameName));
				List<Node> nodes = configRepository.getZhxDataConfigs(gameName);
				if (nodes != null) {
					data.put("zhx", nodes);
				}
				data.put("bigRewards", configRepository.getJackpotDataConfigs(gameName));*/
				Object data = GamesConfigCache.configs.get(gameName);
				map.put(gameName, data);
				list.add(map);
			}
			response.put("gameSettings", list);
		}
	}

}
